package com.lkd.job;

import com.lkd.common.VMSystem;
import com.lkd.dao.TaskDao;
import com.lkd.entity.UserCountEntity;
import com.lkd.feign.UserService;
import com.lkd.vo.UserVO;
import com.xxl.job.core.handler.annotation.XxlJob;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;

import java.time.Duration;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Component
public class UserTaskCountJob {
    @Autowired
    private TaskDao taskDao;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private UserService userService;

    @XxlJob("userTaskCount")
    public void userTaskCount(){
        //1.获取所有运营和运维人员的列表
        List<UserVO> allOperators = userService.getAllOperators(); //所有运营人员
        List<UserVO> allRepairers = userService.getAllRepairers(); //所有运维人员

        allOperators.addAll(allRepairers);

        //2.查询本地所有未完成的工单
        List<UserCountEntity> userIdTaskCount = taskDao.getUserIdTaskCount();
        //转成map
        Map<Long, Long> mapCount = userIdTaskCount.stream().
                collect(Collectors.toMap(UserCountEntity::getUserId, UserCountEntity::getCount));

        //3.将数据放入redis中
        //使用redis的ZSet，key的规则，
        // 以固定字符串（前缀）VMSystem.REGION_TASK_KEY_PREF+日期+区域+人员角色（运营/运维）为key，
        // 以人员id做为值，以工单数作为分数  过期时间为1天
        //获取日期
        Set<String> keys = new HashSet<>();
        for (UserVO userVO : allOperators) {
            String key = VMSystem.getUserTaskCountRedisKey(userVO.getRegionId(), userVO.getRoleCode());
            Long count = mapCount.get(userVO.getUserId().longValue());
            stringRedisTemplate.opsForZSet().add(key, String.valueOf(userVO.getUserId()),count == null?0:count);

//            stringRedisTemplate.expire(key,1, TimeUnit.DAYS);
            keys.add(key);
        }

        for (String key : keys) {
            stringRedisTemplate.expire(key, Duration.ofDays(1));
        }

    }


    @XxlJob("redisTest")
    public void redisTest(){
        //1.String 数量比较小，或者数据定期会失效  验证码
        stringRedisTemplate.opsForValue().set("username","zhangsan");

        BoundValueOperations<String, String> password = stringRedisTemplate.boundValueOps("password");
        password.set("123456");
        String s = password.get();

        stringRedisTemplate.opsForValue().increment("count"); //初始化为0 再加1
        stringRedisTemplate.opsForValue().increment("count"); //由1变成2

        //不要把大量不会失效数据放入String 文章数据放入string

        //2.hash 数据量比较大，而且不会失效 文章数据缓存 商品数据缓存
        stringRedisTemplate.opsForHash().put("article","1","坤坤");
        stringRedisTemplate.opsForHash().put("article","2","坤坤2");
        stringRedisTemplate.opsForHash().put("article","3","坤坤3");
        //stringRedisTemplate.opsForHash().multiGet()
        //加减
        //stringRedisTemplate.opsForHash().increment()

        //3.set
        //3.1 点赞 文章/视频 被谁点赞了
        stringRedisTemplate.opsForSet().add("1001","8"); //8号用户点赞了1001号文章
        stringRedisTemplate.opsForSet().add("1001","8"); //8号用户点赞了1001号文章
        //判断是否点赞
        Boolean member = stringRedisTemplate.opsForSet().isMember("1001", "8"); //true 点赞了 false没有点赞
        //删除点赞
        stringRedisTemplate.opsForSet().remove("1001","8");
        //统计set大小
        Long size = stringRedisTemplate.opsForSet().size("1001"); //获取点赞数

        //3.2 获取共同好友  A：[B C D]  B:[C D E]  C: [D E]
        //放入数据
        stringRedisTemplate.opsForSet().add("A","B","C","D");
        stringRedisTemplate.opsForSet().add("B","C","D","E");
        stringRedisTemplate.opsForSet().add("C","D","E");
        //求交集 B C
        stringRedisTemplate.opsForSet().intersectAndStore("B","C","BCfriends");
        //求差集 BCfriends: DE - A:BCD = E
        Set<String> users = stringRedisTemplate.opsForSet().difference("BCfriends", "A");
        System.out.println(users);
        //求并集 A B = BCDE
        //stringRedisTemplate.opsForSet().union()

        //4.list 创建先进先出 先进后出 队列和栈
        stringRedisTemplate.opsForList().leftPush("list","1");
        stringRedisTemplate.opsForList().leftPush("list","2");
        stringRedisTemplate.opsForList().leftPush("list","3");

        String list = stringRedisTemplate.opsForList().rightPop("list");
        String list2 = stringRedisTemplate.opsForList().rightPop("list");
        String list3 = stringRedisTemplate.opsForList().rightPop("list");

        //5.zset 有序集合
        stringRedisTemplate.opsForZSet().add("paihang","坤坤",1000);
        stringRedisTemplate.opsForZSet().add("paihang","真真",500);
        stringRedisTemplate.opsForZSet().add("paihang","王源",400);
        stringRedisTemplate.opsForZSet().add("paihang","花花",800);
        stringRedisTemplate.opsForZSet().add("paihang","存存",600);

        stringRedisTemplate.opsForZSet().incrementScore("paihang","坤坤",-1);

        //reverse 倒序如果不加正序 byScore 分值范围查询，默认序号  withScores
        Set<String> paihang =
                stringRedisTemplate.opsForZSet().reverseRange("paihang", 0, 3);

        System.out.println(paihang);

        Set<ZSetOperations.TypedTuple<String>> paihang1 = stringRedisTemplate.opsForZSet().reverseRangeWithScores("paihang", 0, 3);
        for (ZSetOperations.TypedTuple<String> data : paihang1) {
            System.out.println(data.getValue() + data.getScore());
        }

        stringRedisTemplate.opsForZSet().add("paihang","坤坤",3000);
    }
}
